﻿''' <summary>
''' Provides the primary container for related game assets and objects.
''' Inherit from GameScene to create the individual levels and game screens for your game.
''' </summary>
''' <remarks>
''' The GameScene is a conceptual container for related game elements. There are various ways to implement the use of scenes,
''' with a common pattern being the use of individual scenes for the title screen, main game screen, and main menu screen.
''' </remarks>
Public MustInherit Class GameScene
    ''' <summary>
    ''' Occurs once per frame after the GameEngine has drawn the scene.
    ''' </summary>
    ''' <remarks></remarks>
    Public Event Draw As EventHandler(Of DrawEventArgs)
    ''' <summary>
    ''' Occurs when the GameScene is loaded.
    ''' </summary>
    ''' <remarks></remarks>
    Public Event Load As EventHandler(Of GameEngineEventArgs)
    ''' <summary>
    ''' Occurs once per frame after the GameEngine as drawn all backgrounds and objects
    ''' in the scene, but before any HUD elements are drawn.
    ''' </summary>
    ''' <remarks></remarks>
    Public Event PreHudDraw As EventHandler(Of DrawEventArgs)
    ''' <summary>
    ''' Occurs once per frame before any drawing occurs.
    ''' </summary>
    ''' <remarks></remarks>
    Public Event Update As EventHandler(Of GameEngineEventArgs)

    'Private _Assets As AssetBank
    Private _Assets As AssetManager

    Private _Backgrounds As New GameBackgroundCollection
    ''' <summary>
    ''' Contains all of the background objects used by this scene.  All enabled backgrounds will be updated and
    ''' all visible backgrounds will be drawn.
    ''' </summary>
    ''' <value></value>
    ''' <returns>The list of GameBackgrounds owned by this scene.</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Backgrounds As GameBackgroundCollection
        Get
            Return _Backgrounds
        End Get
    End Property

    Private _HudLayers As New List(Of HudLayer)
    ''' <summary>
    ''' Contains each of the HUD layers used by this scene.  All visible layers will be updated and drawn.
    ''' </summary>
    ''' <value></value>
    ''' <returns>The list of HudLayers owned by this scene.</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property HudLayers As List(Of HudLayer)
        Get
            Return _HudLayers
        End Get
    End Property

    Private _Objects As New GameObjectCollection
    ''' <summary>
    ''' Contains all of the active GameObjects in use by this scene. All enabled objects will be updated and
    ''' all visible objects will be drawn on each frame by the GameEngine.
    ''' </summary>
    ''' <value></value>
    ''' <returns>The list of GameObjects owned by this scene.</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Objects As GameObjectCollection
        Get
            Return _Objects
        End Get
    End Property

    Private _EnableRaisingEvents As Boolean
    ''' <summary>
    ''' Specifies whether or not this scene raises is game logic related events during execution of the game loop.
    ''' </summary>
    ''' <value></value>
    ''' <returns>True if the scene should raise its events, otherwise false.</returns>
    ''' <remarks></remarks>
    Public Property EnableRaisingEvents() As Boolean
        Get
            Return _EnableRaisingEvents
        End Get
        Set(ByVal value As Boolean)
            _EnableRaisingEvents = value
        End Set
    End Property

    Private _Engine As GameEngine
    ''' <summary>
    ''' Gets the active game engine responsible for this scene.
    ''' </summary>
    ''' <value></value>
    ''' <returns>The GameEngine instance which owns this scene.</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Engine As GameEngine
        Get
            Return _Engine
        End Get
    End Property

    Private _IsLoaded As Boolean
    ''' <summary>
    ''' Determines if the OnLoad method has executed for this scene.
    ''' </summary>
    ''' <value></value>
    ''' <returns>True of the scene is loaded, otherwise false.</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property IsLoaded As Boolean
        Get
            Return _IsLoaded
        End Get
    End Property

    ''' <summary>
    ''' Gets the distinct name of this scene.  Each scene in a game must have
    ''' a unique name.
    ''' </summary>
    ''' <value></value>
    ''' <returns>The unique name of this GameScene.</returns>
    ''' <remarks></remarks>
    Public MustOverride ReadOnly Property Name As String

    ''' <summary>
    ''' Gets the file path to an audio asset with the specified assetName.
    ''' </summary>
    ''' <param name="assetName">The name of the audio asset whose URI should be returned.</param>
    ''' <returns>The URI containing the file path to the specified audio asset if found, otherwise Nothing (Null).</returns>
    ''' <remarks></remarks>
    Public Function GetAudioAsset(ByVal assetName As String) As Uri
        Return _Assets.GetAudioAsset(assetName)
    End Function

    ''' <summary>
    ''' Gets the Bitmap instance for an image asset with the specified assetName.
    ''' </summary>
    ''' <param name="assetName">The name of the image asset Bitmap to return.</param>
    ''' <returns>The Image represented by this Asset name if found, otherwise Nothing (Null).</returns>
    ''' <remarks></remarks>
    Public Function GetImageAsset(ByVal assetName As String) As Bitmap
        Return _Assets.GetImageAsset(assetName)
    End Function

    Public Function GetFlagAsset(assetName As String) As Boolean
        Return _Assets.GetFlagAsset(assetName)
    End Function

    Public Function GetIntegerAsset(assetName As String) As Integer
        Return _Assets.GetIntegerAsset(assetName)
    End Function

    Public Function GetSingleAsset(assetName As String) As Single
        Return _Assets.GetSingleAsset(assetName)
    End Function

    Public Function GetStringAsset(assetName As String) As String
        Return _Assets.GetStringAsset(assetName)
    End Function

    ''' <summary>
    ''' Gets an array of all background objects sorted by their z-order.
    ''' </summary>
    ''' <returns>An array of GameBackground sorted by z-order.</returns>
    ''' <remarks></remarks>
    Public Function GetSceneBackgrounds() As GameBackground()
        Return _Backgrounds.ToZOrderedArray
    End Function

    ''' <summary>
    ''' Gets an array of all game objects sorted by their z-order.
    ''' </summary>
    ''' <returns>An array of GameObject sorted by z-order.</returns>
    ''' <remarks></remarks>
    Public Function GetSceneObjects() As GameObject()
        Return _Objects.ToZOrderedArray
    End Function

    Protected Friend Sub SetEngine(ByVal engine As GameEngine)
        _Engine = engine
        If _Engine IsNot Nothing Then
            _Assets = engine.Resources
        Else
            _Assets = Nothing
        End If
    End Sub

    Protected Friend Overridable Sub OnDraw(ByVal e As DrawEventArgs)
        If _EnableRaisingEvents Then RaiseEvent Draw(Me, e)
    End Sub

    Protected Friend Overridable Sub OnLoad(ByVal e As GameEngineEventArgs)
        If _IsLoaded Then Exit Sub
        If _EnableRaisingEvents Then RaiseEvent Load(Me, e)
        _IsLoaded = True
    End Sub

    Protected Friend Overridable Sub OnPreHudDraw(e As DrawEventArgs)
        If _EnableRaisingEvents Then RaiseEvent PreHudDraw(Me, e)
    End Sub

    Protected Friend Overridable Sub OnUpdate(ByVal e As GameEngineEventArgs)
        If _EnableRaisingEvents Then RaiseEvent Update(Me, e)
    End Sub
End Class
